﻿using JNPF.Basics.Logic;
using JNPF.Basics.Models;
using JNPF.Basics.Models.Permission.Dtos.User;
using JNPF.Utils;
using JNPF.Utils.Controller;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace JNPF.Basics.Controller
{
    /// <summary>
    /// 用户管理
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// 日 期：2017.09.21 
    /// </summary>
    [Route("api/Permission/[controller]")]
    public class UsersController : BaseApiController
    {
        private UserBll userBll = new UserBll();
        private OrganizeBll organizeBll = new OrganizeBll();
        private UserOnlineBll userOnlineBll = new UserOnlineBll();
        private PositionBll positionBll = new PositionBll();
        private RoleBll roleBll = new RoleBll();

        #region GET
        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResponseResult> GetList(UserListQuery input)
        {
            var pageinput = input.MapTo<PageInput>();
            if (!input.organizeId.IsNullOrEmpty())
            {
                var organizeIds = await GetSubOrganizeIds(input.organizeId);
                pageinput.queryJson = new { organizeId = string.Join(",", organizeIds.ToArray()) }.ToJson();
            }
            var data = await userBll.GetList(pageinput);
            var outputList = new List<UserListOutput>();
            data.list.ForEach(x => outputList.Add(new UserListOutput
            {
                id = x.Id,
                account = x.Account,
                realName = x.RealName,
                creatorTime = x.CreatorTime,
                department = organizeBll.GetName(x.OrganizeId),
                description = x.Description,
                enabledMark = x.EnabledMark,
                gender = x.Gender,
                mobilePhone = x.MobilePhone,
                position = positionBll.GetName(x.PositionId),
                roleName = roleBll.GetName(x.RoleId),
                sortCode = x.SortCode
            })
            );
            var output = new PageResult<UserListOutput>
            {
                list = outputList,
                pagination = data.pagination
            };
            return Success(output);
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("All")]
        public async Task<ResponseResult> GetList()
        {
            var data = (await userBll.GetList()).FindAll(t => t.EnabledMark.Equals(1));
            var user = UserProvider.Instance.Get();
            //data.Remove(data.FindAll(users => users.Id == user.UserId).FirstOrDefault());
            var output = data.Select(x => new UserListAllOutput()
            {
                account = x.Account,
                department = organizeBll.GetName(x.OrganizeId),
                gender = x.Gender.ToString(),
                headIcon = "/api/Common/Image/userAvatar/" + x.HeadIcon,
                id = x.Id,
                quickQuery = x.QuickQuery,
                realName = x.RealName,
                sortCode = x.SortCode
            }).ToList();
            return Success(new { list = output });
        }

        /// <summary>
        /// 获取下拉框（公司+部门+用户）
        /// </summary>
        /// <returns></returns>
        [HttpGet("Selector")]
        public async Task<ResponseResult> GetSelector()
        {
            var organizeList = (await organizeBll.GetList()).FindAll(t => t.EnabledMark.Equals(1));
            var userList = (await userBll.GetList()).FindAll(t => t.EnabledMark.Equals(1));
            var organizeTreeList = organizeList.Select(x => new UserSelectorOutput
            {
                id = x.Id,
                parentId = x.ParentId,
                fullName = x.FullName,
                type = x.Category,
                enabledMark = x.EnabledMark,
                icon = "icon-ym icon-ym-tree-organization3"
            }).ToList();
            var treeList = userList.Select(x => new UserSelectorOutput
            {
                id = x.Id,
                parentId = x.OrganizeId,
                fullName = x.RealName + "/" + x.Account,
                type = "user"
            }).ToList();
            treeList = treeList.Concat(organizeTreeList).ToList();
            return Success(new { list = treeList.ToTree("-1") });
        }

        /// <summary>
        /// 获取信息
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<ResponseResult> GetInfo(string id)
        {
            var entity = await userBll.GetInfo(id);
            var output = entity.MapTo<UserInfoOutput>();
            output.roleId = output.roleId.IsNullOrEmpty() ? null : output.roleId;
            output.positionId = output.positionId.IsNullOrEmpty() ? null : output.positionId;
            return Success(output);
        }

        /// <summary>
        /// 获取在线用户列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("Online")]
        public async Task<ResponseResult> GetUsersOnline(KeywordInput input)
        {
            var output = await userOnlineBll.GetList();
            if (input.keyword.IsNotEmptyOrNull())
            {
                output = output.FindAll(x => x.userName.Contains(input.keyword));
            }
            return Success(output);
        }
        #endregion

        #region POST
        /// <summary>
        /// 新建
        /// </summary>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResponseResult> Create([FromBody] UserCrInput input)
        {
            if (await userBll.IsExistByAccount(input.account, null))
            {
                return Error("账户已存在");
            }
            var entity = InputToEntity(input);
            await userBll.Create(entity);
            return Success("新建成功");
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task<ResponseResult> Delete(string id)
        {
            var entity = await userBll.GetInfo(id);
            if (entity != null)
            {
                await userBll.Delete(entity);
            }
            return Success("删除成功");
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id">主键</param>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task<ResponseResult> Update(string id, [FromBody] UserUpInput input)
        {
            if (await userBll.IsExistByAccount(input.account, id))
            {
                return Error("账户已存在");
            }
            var entity = InputToEntity(input.MapTo<UserCrInput>());
            await userBll.Update(id, entity);
            await userOnlineBll.Delete(id);
            CacheFactory.Cache.Remove(CacheKey.USERAUTHORIZE + id);
            return Success("更新成功");
        }

        /// <summary>
        /// 更新状态
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpPut("{id}/Actions/State")]
        public async Task<ResponseResult> UpdateState(string id)
        {
            var entity = await userBll.GetInfo(id);
            entity.EnabledMark = entity.EnabledMark == 1 ? 0 : 1;
            var isOk = await userBll.UpdateState(id, entity);

            return isOk > 0 ? Success("更新成功") : Error("更新失败");
        }

        /// <summary>
        /// 更新密码
        /// </summary>
        /// <param name="id">主键</param>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPost("{id}/Actions/ResetPassword")]
        public async Task<ResponseResult> ResetPassword(string id, [FromBody] UserResetPasswordInput input)
        {
            if (!input.userPassword.Equals(input.validatePassword))
            {
                return Error("密码不一致");
            }
            var entity = await userBll.GetInfo(id);
            entity.Password = input.userPassword;
            var isOk = await userBll.UpdatePassword(id, entity);
            await userOnlineBll.Delete(id);
            CacheFactory.Cache.Remove(CacheKey.USERAUTHORIZE + id);
            return isOk > 0 ? Success("更新成功") : Error("更新失败");
        }

        /// <summary>
        /// 强制下线
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpDelete("Online/{id}")]
        public async Task<ResponseResult> DeleteUsersOnline(string id)
        {
            await userOnlineBll.Delete(id);
            return Success("下线成功");
        }
        #endregion

        #region Method
        /// <summary>
        /// 下属机构
        /// </summary>
        /// <param name="organizeId"></param>
        /// <returns></returns>
        private async Task<List<string>> GetSubOrganizeIds(string organizeId)
        {
            var data = (await organizeBll.GetList()).FindAll(x => x.EnabledMark.Equals(1));
            data = data.TreeChildNode(organizeId, t => t.Id, t => t.ParentId);
            return data.Select(m => m.Id).ToList();
        }

        /// <summary>
        /// 入参转换实体
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private UserEntity InputToEntity(UserCrInput input)
        {
            var entity = new UserEntity();
            entity.Account = input.account;
            entity.RealName = input.realName;
            entity.OrganizeId = input.organizeId;
            entity.ManagerId = input.managerId;
            entity.PositionId = input.positionId;
            entity.RoleId = input.roleId;
            entity.Description = input.description;
            entity.Gender = input.gender;
            entity.Nation = input.nation;
            entity.NativePlace = input.nativePlace;
            entity.EntryDate = input.entryDate == 0 ? DateTime.Now : CommonHelper.GetDateTime(input.entryDate.ToString());
            entity.CertificatesType = input.certificatesType;
            entity.CertificatesNumber = input.certificatesNumber;
            entity.Education = input.education;
            entity.Birthday = input.birthday == 0 ? DateTime.Now : CommonHelper.GetDateTime(input.birthday.ToString());
            entity.TelePhone = input.telePhone;
            entity.Landline = input.landline;
            entity.MobilePhone = input.mobilePhone;
            entity.Email = input.email;
            entity.UrgentContacts = input.urgentContacts;
            entity.UrgentTelePhone = input.urgentTelePhone;
            entity.PostalAddress = input.postalAddress;
            entity.HeadIcon = input.headIcon;
            entity.SortCode = input.sortCode;
            entity.EnabledMark = input.enabledMark;
            return entity;
        }
        #endregion
    }
}
